package com.afeng.api.framework.exception;

import com.afeng.api.framework.base.ApiResult;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;

/**
 * 全局异常处理器
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 全局异常捕捉处理
     */
    @ExceptionHandler(value = {Exception.class})
    public ModelAndView handleException(HttpServletRequest request, Exception e) {
        log.debug(e.getMessage(), e);
        ModelAndView view = new ModelAndView();
        MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
        jsonView.setAttributesMap(JSON.parseObject(JSON.toJSONString(ApiResult.fail("异常错误"))));
        view.setView(jsonView);
        return view;
    }

    /**
     * 处理API自定义异常
     */
    @ResponseBody
    @ExceptionHandler(ApiException.class)
    public ApiResult handleApiException(ApiException e) {
        log.debug(e.getMessage(), e);
        return ApiResult.fail(e.getMsg());
    }


    @ResponseBody
    @ExceptionHandler(DuplicateKeyException.class)
    public ApiResult handleDuplicateKeyException(DuplicateKeyException e) {
        log.debug(e.getMessage(), e);
        return ApiResult.fail("数据库中已存在该记录");
    }

    @ResponseBody
    @ExceptionHandler(NoHandlerFoundException.class)
    public ApiResult handlerNoFoundException(NoHandlerFoundException e) {
        log.debug(e.getMessage(), e);
        return ApiResult.fail("路径不存在，请检查路径是否正确");
    }

    @ResponseBody
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ApiResult handleException(HttpRequestMethodNotSupportedException e) {
        log.debug(e.getMessage(), e);
        return ApiResult.fail("请求方法错误");
    }

    @ResponseBody
    @ExceptionHandler(ValidationException.class)
    public ApiResult handle(ValidationException exception) {
        log.debug(exception.getMessage(), exception);
        String msg = "参数错误";
        if (exception instanceof ConstraintViolationException) {
            ConstraintViolationException exs = (ConstraintViolationException) exception;
            Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
            for (ConstraintViolation<?> item : violations) {
                if (StringUtils.isNotEmpty(item.getMessage())) {
                    msg = item.getMessage();
                    break;
                }
            }
        } else {
            msg = exception.getMessage();
        }
        return ApiResult.fail(msg);
    }

}
